﻿using adb群控.model;
using adb群控.service;
using adb群控.util;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace adb群控
{
    public partial class Device : Form
    {

        public model.Device device;

        public String cpuCmd1 ;

        /// <summary>
        /// 定义图片设置委托
        /// </summary>
        private delegate void setPictureImagePath();

        private int failCount = 0;



        private Socket clientSocket;

        Thread myThread;


        /// <summary>
        /// 定义图片设置委托
        /// </summary>
        private delegate void AynsEvent();

        public Device(model.Device device)
        {
            InitializeComponent();
            this.device = device;
            this.Text = device.Name;
            cpuCmd1 = String.Format("host:transport:{0}", device.Name);

        }


        private void Form1_Load(object sender, EventArgs e)
        {
            myThread = new Thread(ListenConnect);
            myThread.IsBackground = true;
            myThread.Start();

        }

        #region 初始化设备
        /// <summary>
        /// 初始化设备信息
        /// </summary>
        private void initDevice()
        {
            CmdUtil cmd = new CmdUtil();
            String cmdHeader = "adb -s  " + device.Name + " ";
            String startMinicapServerCmd = cmdHeader + String.Format(" shell LD_LIBRARY_PATH=/data/local/tmp /data/local/tmp/minicap -P {0}x{1}@{0}x{1}/0", device.Higth.Trim(), device.Width.Trim());
            cmd.excute(startMinicapServerCmd);
            String proxyPortCmd = cmdHeader + " forward tcp:" + device.Port + " localabstract:minicap";//执行代理端口
            cmd.excute(proxyPortCmd);
        }
        #endregion

        #region 处理服务连接信息
        private Banner banner = new Banner();
        byte[] chunk = new byte[4096000];
        /// <summary>
        /// 连接数据处理
        /// </summary>
        private void ListenConnect()
        {
            initDevice();
            //设定服务器IP地址  
            IPAddress ip = IPAddress.Parse("127.0.0.1");
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            try
            {
                clientSocket.Connect(new IPEndPoint(ip, device.Port)); //配置服务器IP与端口  
                Debug.WriteLine("连接服务器成功");
                int reallen;
                int readBannerBytes = 0;
                int bannerLength = 2;
                int readFrameBytes = 0;
                int frameBodyLength = 0;
                byte[] frameBody = new byte[0];
                while ((reallen = clientSocket.Receive(chunk)) != 0)
                {
                    if (this.failCount >= 5)
                    {
                        Debug.WriteLine("线程退出,图片刷新次数为：" + this.failCount);
                        clientSocket.Close();
                        myThread.Abort();
                        return;
                    }
                    for (int cursor = 0, len = reallen; cursor < len;)
                    {
                        //读取banner信息
                        if (readBannerBytes < bannerLength)
                        {
                            switch (readBannerBytes)
                            {
                                case 0:
                                    banner.Version = chunk[cursor];
                                    break;
                                case 1:
                                    banner.Length = bannerLength = chunk[cursor];
                                    break;
                                case 2:
                                case 3:
                                case 4:
                                case 5:
                                    banner.Pid += (chunk[cursor] << ((cursor - 2) * 8));
                                    break;
                                case 6:
                                case 7:
                                case 8:
                                case 9:
                                    banner.RealWidth += (chunk[cursor] << ((cursor - 6) * 8));
                                    break;
                                case 10:
                                case 11:
                                case 12:
                                case 13:
                                    banner.RealHeight += (chunk[cursor] << ((cursor - 10) * 8));
                                    break;
                                case 14:
                                case 15:
                                case 16:
                                case 17:
                                    banner.VirtualWidth += (chunk[cursor] << ((cursor - 14) * 8));
                                    break;
                                case 18:
                                case 19:
                                case 20:
                                case 21:
                                    banner.VirtualHeight += (chunk[cursor] << ((cursor - 2) * 8));
                                    break;
                                case 22:
                                    banner.Orientation += chunk[cursor] * 90;
                                    break;
                                case 23:
                                    banner.Quirks = chunk[cursor];
                                    break;
                            }
                            cursor += 1;
                            readBannerBytes += 1;
                        }
                        //读取每张图片的头4个字节(图片大小)
                        else if (readFrameBytes < 4)
                        {
                            frameBodyLength += (chunk[cursor] << (readFrameBytes * 8));
                            cursor += 1;
                            readFrameBytes += 1;
                        }
                        else
                        {
                            //读取图片内容
                            if (len - cursor >= frameBodyLength)
                            {
                                frameBody = frameBody.Concat(subByteArray(chunk, cursor, cursor + frameBodyLength)).ToArray();
                                String result = setPictureImage(frameBody);
                                if (result.Equals("false"))
                                {
                                    this.failCount = failCount + 1;
                                }
                                else
                                {
                                    this.failCount = 0;
                                }
                                cursor += frameBodyLength;
                                frameBodyLength = readFrameBytes = 0;
                                frameBody = new byte[0];
                            }
                            else
                            {
                                frameBody = frameBody.Concat(subByteArray(chunk, cursor, len)).ToArray();
                                frameBodyLength -= len - cursor;
                                readFrameBytes += len - cursor;
                                cursor = len;
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine("计算页面显示异常！" + e.Message);
                return;
            }

        }

        /// <summary>
        /// 用于提取byte数组
        /// </summary>
        /// <param name="arr">源数组</param>
        /// <param name="start">起始位置</param>
        /// <param name="end">结束位置</param>
        /// <returns>提取后的数组</returns>
        private byte[] subByteArray(byte[] arr, int start, int end)
        {
            int len = end - start;
            byte[] newbyte = new byte[len];
            Buffer.BlockCopy(arr, start, newbyte, 0, len);
            return newbyte;
        }

        private String setPictureImage(byte[] data)
        {
            Util util = new Util();
            // Debug.WriteLine(util.hexToString(data));
            try
            {
                this.Invoke(new setPictureImagePath(delegate ()
                {
                    MemoryStream stmBLOBData = new MemoryStream(data);

                    pictureBox1.Image = Image.FromStream(stmBLOBData);
                }));
                return "success";
            }
            catch (Exception e)
            {

                Debug.WriteLine("图片转换线程错误" + e.Message);
                return "false";
            }

        }
        #endregion


        private void button1_Click(object sender, EventArgs e)
        {
            AynsEvent AsynEvent = new AynsEvent(delegate ()
            {
                CmdUtil cmd = new CmdUtil();
                String cmdSendMessage = String.Format("adb -s {1} shell input text \"{0}\"", txt_message.Text, device.Name);
                cmd.excutex(cmdSendMessage);
            });

            AsynEvent.BeginInvoke(null, null);
        }

        private void 返回ToolStripMenuItem_Click(object sender, EventArgs e)
        {

            AynsEvent AsynEvent = new AynsEvent(delegate ()
            {
                Service s = new Service();
                String cmdSendHomeMessage = String.Format("shell:command input keyevent  \"{0}\"", "4");
                s.sendMessageToAdbNotRec(this.cpuCmd1, cmdSendHomeMessage);
            });

            AsynEvent.BeginInvoke(null, null);


        }

        private void homeToolStripMenuItem_Click(object sender, EventArgs e)
        {

            AynsEvent AsynEvent = new AynsEvent(delegate ()
            {
                Service s = new Service();
                String cmdSendHomeMessage = String.Format("shell:command input keyevent  \"{0}\"", "3");
                s.sendMessageToAdbNotRec(this.cpuCmd1, cmdSendHomeMessage);
            });

            AsynEvent.BeginInvoke(null, null);

        }

        int x0 = 0;
        int y0 = 0;
        long clickStartTime = 0L;

        private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
        {
            x0 = e.X;
            Util util = new Util();
            clickStartTime = util.getNowTime();
            y0 = e.Y;
        }

        private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
        {

            //点击
            AynsEvent AsynEvent = new AynsEvent(delegate ()
            {
                String cmdClick = String.Format("shell:command input tap {1} {2}", device.Name, e.X + "", e.Y + "");
                Service s = new Service();
                s.sendMessageToAdbNotRec(this.cpuCmd1, cmdClick);
            });

            AsynEvent.BeginInvoke(null, null);

        }

        private void Device_FormClosed(object sender, FormClosedEventArgs e)
        {
            if (clientSocket != null)
            {
                clientSocket.Close();
            }
            myThread.Abort();
            Debug.WriteLine("关闭窗口");
        }

        private void Device_KeyDown(object sender, KeyEventArgs e)
        {
            Debug.WriteLine("键盘编码：" + e.KeyData + "====" + e.KeyCode + "===" + e.KeyValue);
        }


    }
}
